﻿Imports System
Imports System.Drawing
Imports System.Collections.Generic
Imports System.Collections
Imports System.Text
Imports System.Runtime.InteropServices
Imports System.IO
Imports System.Globalization
Imports System.Text.RegularExpressions
Imports System.ComponentModel
Imports System.Drawing.Design
Imports System.Net.Mail
Imports System.Net.Mime

Namespace C4F.DevKit.Messaging
    ''' <summary>
    ''' Contains methods for doing MAPI Management.
    ''' </summary>
    <ToolboxItem(True), ToolboxBitmap(GetType(MapiManager))> _
    Public Class MapiManager
        Inherits Component
#Region "Private members"

        Private mapiSession As IntPtr = IntPtr.Zero
        ' Originator of mail.
        Private originator As New MapiManagementNative.MapiRecipDesc()
        Private recipientsList As New ArrayList()
        Private attachments As New ArrayList()
        ' Id of last mail retrieved.
        Private lastMailId As String
        ' Id of next mail retrieved.
        Private lastMassageID As New StringBuilder(600)
        Private profileAdmin As MapiManagementNative.IProfAdmin
        Private mapiTable As MapiManagementNative.IMAPITable
        ' Indicates user has already logged in or not.
        Private isLoggedOn As Boolean
        Dim smtpClient As SmtpClient = Nothing

        ''' <summary>
        ''' Gets pointer to originator of a mail.
        ''' </summary>
        ''' <returns>Pointer to originator.</returns>
        Private Function GetPointerToOriginator() As IntPtr
            originator.recipientClass = MapiOriginator
            Dim originatorSize As Integer = Marshal.SizeOf(GetType(MapiManagementNative.MapiRecipDesc))
            Dim ptrToOriginator As IntPtr = Marshal.AllocHGlobal(originatorSize)
            Marshal.StructureToPtr(originator, ptrToOriginator, False)
            Return ptrToOriginator
        End Function

        ''' <summary>
        ''' Gets pointer to list of recipients of a mail. 
        ''' </summary>
        ''' <param name="recipientCount">Count of recipient.</param>
        ''' <returns>Pointer to list of recipients.</returns>
        Private Function GetPointerToRecipients(ByRef recipientCount As Integer) As IntPtr
            recipientCount = 0
            If recipientsList.Count = 0 Then
                Return IntPtr.Zero
            End If
            Dim recipientSize As Integer = Marshal.SizeOf(GetType(MapiManagementNative.MapiRecipDesc))
            Dim ptrTorecipient As IntPtr = Marshal.AllocHGlobal(recipientsList.Count * recipientSize)
            Dim incerementptr As Integer = CInt(ptrTorecipient)

            For i As Integer = 0 To recipientsList.Count - 1
                Marshal.StructureToPtr(TryCast(recipientsList(i), MapiManagementNative.MapiRecipDesc), CType(incerementptr, IntPtr), False)
                incerementptr += recipientSize
            Next

            recipientCount = recipientsList.Count
            Return ptrTorecipient
        End Function

        ''' <summary>
        ''' Gets pointer to list of attachments to be attached to a mail. 
        ''' </summary>
        ''' <param name="fileCount">Count of attachments.</param>
        ''' <returns>Pointer to list of attachments.</returns>
        Private Function GetPointerToAttachments(ByRef fileCount As Integer) As IntPtr
            fileCount = 0
            If attachments Is Nothing Then
                Return IntPtr.Zero
            End If
            If (attachments.Count <= 0) OrElse (attachments.Count > 100) Then
                Return IntPtr.Zero
            End If

            Dim attachmentTypeSize As Integer = Marshal.SizeOf(GetType(MapiManagementNative.MapiFileDesc))
            Dim ptrToAttachments As IntPtr = Marshal.AllocHGlobal(attachments.Count * attachmentTypeSize)

            Dim fileDescription As New MapiManagementNative.MapiFileDesc()
            fileDescription.position = -1
            Dim incerementptr As Integer = CInt(ptrToAttachments)

            For i As Integer = 0 To attachments.Count - 1
                Dim attachmentPath As String = TryCast(attachments(i), String)
                fileDescription.fileName = Path.GetFileName(attachmentPath)
                fileDescription.pathName = attachmentPath
                Marshal.StructureToPtr(fileDescription, CType(incerementptr, IntPtr), False)
                incerementptr += attachmentTypeSize
            Next

            fileCount = attachments.Count
            Return ptrToAttachments
        End Function

        ''' <summary>
        ''' Deallocates allocated pointers.
        ''' </summary>
        ''' <param name="message">Object of MapiMessage class, whose pointers to be deallocated.</param>
        Private Sub DeallocatePointers(ByVal message As MapiManagementNative.MapiMessage)
            Dim incrementptr As Integer
            If message.originator <> IntPtr.Zero Then
                Marshal.DestroyStructure(message.originator, GetType(MapiManagementNative.MapiRecipDesc))
                Marshal.FreeHGlobal(message.originator)
            End If

            If message.recipients <> IntPtr.Zero Then
                Dim recipientSize As Integer = Marshal.SizeOf(GetType(MapiManagementNative.MapiRecipDesc))
                Dim incerementptr As Integer = CInt(message.recipients)

                For i As Integer = 0 To message.recipientCount - 1
                    Marshal.DestroyStructure(CType(incerementptr, IntPtr), GetType(MapiManagementNative.MapiRecipDesc))
                    incrementptr += recipientSize
                Next
                Marshal.FreeHGlobal(message.recipients)
            End If

            If message.files <> IntPtr.Zero Then
                Dim fileTypeSize As Integer = Marshal.SizeOf(GetType(MapiManagementNative.MapiFileDesc))

                Dim incerementptr As Integer = CInt(message.files)

                For i As Integer = 0 To message.fileCount - 1
                    Marshal.DestroyStructure(CType(incerementptr, IntPtr), GetType(MapiManagementNative.MapiFileDesc))
                    incrementptr += fileTypeSize
                Next
                Marshal.FreeHGlobal(message.files)
            End If
            lastMailId = Nothing
            originator = New MapiManagementNative.MapiRecipDesc()
            recipientsList.Clear()
            attachments.Clear()
        End Sub

        ''' <summary>
        ''' Attaches files to a mail.
        ''' </summary>
        ''' <param name="attachmentFilepathList">Fully qualified name of file to be attached.</param>
        Private Sub AttachFile(ByVal attachmentFilepathList As List(Of String))
            If attachmentFilepathList IsNot Nothing Then
                For index As Integer = 0 To attachmentFilepathList.Count - 1
                    attachments.Add(attachmentFilepathList(index))
                Next
            End If
        End Sub

        ''' <summary>
        ''' Adds recipients of a mail.
        ''' </summary>
        ''' <param name="recipients">Email address of recipient.</param>
        ''' <param name="recipientlistType">Type of recipient of a mail.</param>
        ''' <returns>True,if successful.</returns>
        Private Function AddReceipent(ByVal recipients As List(Of String), ByVal recipientlistType As String) As Boolean
            If recipients IsNot Nothing Then
                For index As Integer = 0 To recipients.Count - 1
                    Dim recepient As New MapiManagementNative.MapiRecipDesc()
                    Dim expression As New Regex(MAPIResource.EmailValidationExpression)
                    Dim matchEmailAddress As Match = expression.Match(recipients(index))
                    If matchEmailAddress.Success Then
                        recepient.name = recipients(index)
                    Else
                        Throw New ArgumentException(MAPIResource.InvalidEmailAdd)
                    End If

                    Select Case recipientlistType
                        Case "Cc"
                            recepient.recipientClass = MapiCc
                            Exit Select
                        Case "To"
                            recepient.recipientClass = MapiTo
                            Exit Select
                        Case "Bcc"
                            recepient.recipientClass = MapiBcc
                            Exit Select
                    End Select
                    recipientsList.Add(recepient)
                Next
            End If
            Return True
        End Function

        ''' <summary>
        ''' Gets available mails.
        ''' </summary>
        ''' <param name="mailFetchFlag">Specifies which mails to be fetched.</param>
        ''' <returns>List of mails fetched.</returns>
        Private Function GetAvailableMails(ByVal mailFetchFlag As Integer) As List(Of Mail)
            If Not Me.isLoggedOn Then
                Throw New MapiManagerException(MAPIResource.NotAvailableMapiSession)
            End If

            lastMailId = Nothing
            Dim mailList As New List(Of Mail)()
            Dim result As MAPIResult
            Dim index As Integer = 0
            Dim flagToGoNext As Boolean = True

            Try
                While flagToGoNext
                    result = CType(MapiManagementNative.MAPIFindNext(mapiSession, IntPtr.Zero, Nothing, lastMailId, mailFetchFlag, 0, _
                     lastMassageID), MAPIResult)

                    If result = MAPIResult.NoMessages Then
                        flagToGoNext = False
                        Exit While
                    End If

                    If result <> MAPIResult.Success Then
                        Throw New MapiManagerException(result.ToString())
                    End If

                    lastMailId = lastMassageID.ToString()
                    Dim ptrToMessage As IntPtr = IntPtr.Zero

                    result = CType(MapiManagementNative.MAPIReadMail(mapiSession, IntPtr.Zero, lastMailId, MapiPeek, 0, ptrToMessage), MAPIResult)

                    If (result <> MAPIResult.Success) OrElse (ptrToMessage = IntPtr.Zero) Then
                        Throw New MapiManagerException(result.ToString())
                    End If

                    Dim fetchedMessage As New MapiManagementNative.MapiMessage()

                    Marshal.PtrToStructure(ptrToMessage, fetchedMessage)

                    Dim originator As New MapiManagementNative.MapiRecipDesc()

                    If fetchedMessage.originator <> IntPtr.Zero Then
                        Marshal.PtrToStructure(fetchedMessage.originator, originator)
                    Else
                        Throw New MapiManagerException(MAPIResource.OriginatorNotFound)
                    End If

                    mailList.Add(New Mail())
                    mailList(index).m_id = lastMailId
                    mailList(index).Subject = fetchedMessage.subject
                    mailList(index).m_from = originator.address.Substring(5)
                    mailList(index).m_unread = (fetchedMessage.flags And MapiUnread) <> 0
                    mailList(index).Attachments = Nothing

                    If fetchedMessage.dateReceived IsNot Nothing Then
                        mailList(index).m_date = DateTime.ParseExact(fetchedMessage.dateReceived, "yyyy/MM/dd HH:mm", DateTimeFormatInfo.InvariantInfo)
                    Else
                        Throw New MapiManagerException(MAPIResource.DateNotFound)
                    End If

                    If Not ((result <> MAPIResult.Success) OrElse (ptrToMessage = IntPtr.Zero)) Then

                        If (fetchedMessage.fileCount > 0) AndAlso (fetchedMessage.fileCount < 100) AndAlso (fetchedMessage.files <> IntPtr.Zero) Then

                            mailList(index).Attachments = New List(Of String)(fetchedMessage.fileCount)

                            Dim fileDesriptionSize As Integer = Marshal.SizeOf(GetType(MapiManagementNative.MapiFileDesc))
                            Dim fileDesription As New MapiManagementNative.MapiFileDesc()
                            Dim incrementPtr As Integer = CInt(fetchedMessage.files)

                            For i As Integer = 0 To fetchedMessage.fileCount - 1

                                Marshal.PtrToStructure(CType(incrementPtr, IntPtr), fileDesription)

                                incrementPtr += fileDesriptionSize

                                If fileDesription.flags = 0 Then
                                    mailList(index).Attachments.Add(fileDesription.fileName)
                                End If

                            Next

                        End If

                        If (fetchedMessage.recipientCount > 0) AndAlso (fetchedMessage.recipientCount < 100) AndAlso (fetchedMessage.recipients <> IntPtr.Zero) Then
                            Dim recipientSize As Integer = Marshal.SizeOf(GetType(MapiManagementNative.MapiRecipDesc))

                            Dim recipientDesription As New MapiManagementNative.MapiRecipDesc()
                            Dim incrementPtr As Integer = CInt(fetchedMessage.recipients)

                            For i As Integer = 0 To fetchedMessage.recipientCount - 1

                                Marshal.PtrToStructure(CType(incrementPtr, IntPtr), recipientDesription)

                                Select Case recipientDesription.recipientClass
                                    Case MapiTo
                                        If (mailList(index).ToList Is Nothing) Then
                                            mailList(index).ToList = New List(Of String)()
                                        End If
                                        mailList(index).ToList.Add(recipientDesription.address.Substring(5))
                                        Exit Select
                                    Case MapiCc
                                        If (mailList(index).CcList Is Nothing) Then
                                            mailList(index).CcList = New List(Of String)()
                                        End If
                                        mailList(index).CcList.Add(recipientDesription.address.Substring(5))
                                        Exit Select
                                    Case MapiBcc
                                        If (mailList(index).BccList Is Nothing) Then
                                            mailList(index).BccList = New List(Of String)()
                                        End If
                                        mailList(index).BccList.Add(recipientDesription.address.Substring(5))
                                        Exit Select
                                End Select
                                incrementPtr += recipientSize
                            Next
                        End If
                        mailList(index).MessageBody = fetchedMessage.messageBody
                    Else
                        Throw New MapiManagerException(result.ToString())
                    End If
                    result = CType(MapiManagementNative.MAPIFreeBuffer(ptrToMessage), MAPIResult)
                    index += 1
                End While

            Catch exception As Exception
                Throw New MapiManagerException(exception.Message)
            End Try

            lastMailId = Nothing
            mailList.Reverse()
            Return mailList
        End Function
#End Region

#Region "Constants"

        Private Const MapiOriginator As Integer = 0
        Private Const MapiTo As Integer = 1
        Private Const MapiCc As Integer = 2
        Private Const MapiBcc As Integer = 3
        Private Const MapiPeek As Integer = 128
        Private Const MapiSuprAttach As Integer = 2048
        Private Const MapiEnvOnly As Integer = 64
        Private Const MapiUnread As Integer = 1

        ' Allow 512 char returned ID.
        Private Const MapiLongMsgID As Integer = 16384
        ' Only unread messages.
        Private Const MapiUnreadOnly As Integer = 32

#End Region

#Region "Constructor"

        ''' <summary>
        ''' Creates instance of MapiManager Class.
        ''' </summary>
        Public Sub New()
            Dim result As MAPIResult

            ' Initializes messaging system.
            result = CType(MapiManagementNative.MAPIInitialize(IntPtr.Zero), MAPIResult)

            If result = MAPIResult.Success Then
                result = CType(MapiManagementNative.MAPIAdminProfiles(0, profileAdmin), MAPIResult)
            End If
        End Sub

#End Region

#Region "Public Methods - Mail"

#Region "Logon"

        ''' <summary>
        ''' Starts a MAPI session and logs in using the specified profile.
        ''' </summary>
        ''' <param name="profileName">Name of profile to be logged in.</param>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        ''' <exception cref="InvalidOperationException">Exception raised when there is MAPI session already existing.</exception>
        ''' <exception cref="ArgumentNullException">The required parameter is null or empty.</exception>
        ''' <exception cref="ArgumentException">The specified parameter is not valid.</exception>
        Public Sub Logon(ByVal profileName As String)
            ' Check if profileName is null or empty.
            If String.IsNullOrEmpty(profileName) Then
                Throw New ArgumentNullException(MAPIResource.ParameterProfileName)
            End If
            ' Check if user has already logged on.
            If isLoggedOn Then
                Throw New InvalidOperationException(MAPIResource.MapiSessionAvailable)
            End If

            '#Region "Commented because of known issue of GetAvailableProfiles"
            'List<string> profileList = this.GetAvailableProfiles();
            'if (!profileList.Contains(profileName))
            '{
            '    throw new ArgumentException(MAPIResource.ProfileNotExist);
            '}
            '#End Region

            Dim result As MAPIResult
            Try
                ' Logon to specified profile.
                result = CType(MapiManagementNative.MAPILogon(IntPtr.Zero, profileName, String.Empty, 0, 0, mapiSession), MAPIResult)
                If result <> MAPIResult.Success Then
                    Throw New MapiManagerException(result.ToString())
                Else
                    Me.isLoggedOn = True
                End If
            Catch exception As Exception
                Throw New MapiManagerException(exception.Message, exception.InnerException)
            End Try
        End Sub

        ''' <summary>
        ''' Starts a MAPI session and logs in using default profile.
        ''' </summary>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        ''' <exception cref="InvalidOperationException">Exception raised when there is MAPI session already existing.</exception>
        Public Sub Logon()
            ' Check if user has already logged on.
            If isLoggedOn Then
                Throw New InvalidOperationException(MAPIResource.MapiSessionAvailable)
            End If

            Dim result As MAPIResult
            Try
                ' Logon to default profile.
                result = CType(MapiManagementNative.MAPILogon(IntPtr.Zero, String.Empty, String.Empty, 0, 0, mapiSession), MAPIResult)
                If result <> MAPIResult.Success Then
                    Throw New MapiManagerException(result.ToString())
                Else
                    Me.isLoggedOn = True
                End If
            Catch exception As Exception
                Throw New MapiManagerException(exception.Message, exception.InnerException)
            End Try
        End Sub


#End Region

#Region "SendMail"

#Region "Use of unmanaged Api"
        ''' <summary>
        ''' Send a mail to the specified receivers.
        ''' </summary>
        ''' <param name="mail">Mail to be sent.</param>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        ''' <exception cref="ArgumentNullException">The required parameter is null or empty.</exception>
        Public Sub SendMail(ByVal mail As Mail)
            ' Check if mailTobeSent is null.
            If mail Is Nothing Then
                Throw New ArgumentNullException(MAPIResource.ParameterMailTobeSent)
            Else
                SendMail(mail.ToList, mail.CcList, mail.BccList, mail.Subject, mail.MessageBody, mail.Attachments)
            End If
        End Sub

        ''' <summary>
        ''' Send a mail to the specified receivers.
        ''' </summary>
        ''' <param name="toList">List of receivers who should be in ‘To’ list.</param>
        ''' <param name="subject">Subject line of the mail.</param>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        ''' <exception cref="ArgumentNullException">The required parameter is null or empty.</exception>
        Public Sub SendMail(ByVal toList As List(Of String), ByVal subject As String)
            ' Send mail.
            SendMail(toList, Nothing, Nothing, subject, String.Empty, Nothing)
        End Sub

        ''' <summary>
        ''' Send a mail to the specified receivers.
        ''' </summary>
        ''' <param name="toList">List of receivers who should be in ‘To’ list.</param>
        ''' <param name="subject">Subject line of the mail.</param>
        ''' <param name="messageBody">Content of the mail body.</param>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        ''' <exception cref="ArgumentNullException">The required parameter is null or empty.</exception>
        Public Sub SendMail(ByVal toList As List(Of String), ByVal subject As String, ByVal messageBody As String)
            ' Send mail.
            SendMail(toList, Nothing, Nothing, subject, messageBody, Nothing)
        End Sub

        ''' <summary>
        ''' Send a mail to the specified receivers.
        ''' </summary>
        ''' <param name="toList">List of receivers who should be in ‘To’ list.</param>
        ''' <param name="subject">Subject line of the mail.</param>
        ''' <param name="messageBody">Content of the mail body.</param>
        ''' <param name="attachmentList">List of paths of the files to be attached with the mail.</param>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        ''' <exception cref="ArgumentNullException">The required parameter is null or empty.</exception>
        Public Sub SendMail(ByVal toList As List(Of String), ByVal subject As String, ByVal messageBody As String, ByVal attachmentList As List(Of String))
            ' Send mail.
            SendMail(toList, Nothing, Nothing, subject, messageBody, attachmentList)
        End Sub

        ''' <summary>
        ''' Send a mail to the specified receivers.
        ''' </summary>
        ''' <param name="toList">List of receivers who should be in ‘To’ list.</param>
        ''' <param name="ccList">List of receivers who should be in ‘Cc’ list.</param>
        ''' <param name="subject">Subject line of the mail.</param>
        ''' <param name="messageBody">Content of the mail body.</param>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        ''' <exception cref="ArgumentNullException">The required parameter is null or empty.</exception>
        Public Sub SendMail(ByVal toList As List(Of String), ByVal ccList As List(Of String), ByVal subject As String, ByVal messageBody As String)
            ' Send mail.
            SendMail(toList, ccList, Nothing, subject, messageBody, Nothing)
        End Sub

        ''' <summary>
        ''' Send a mail to the specified receivers.
        ''' </summary>
        ''' <param name="toList">List of receivers who should be in ‘To’ list.</param>
        ''' <param name="ccList">List of receivers who should be in ‘Cc’ list.</param>
        ''' <param name="bccList">List of receivers who should be in ‘Bcc’ list.</param>
        ''' <param name="subject">Subject line of the mail.</param>
        ''' <param name="messageBody">Content of the mail body.</param>
        ''' <param name="attachmentList">List of paths of the files to be attached with the mail.</param>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        ''' <exception cref="ArgumentNullException">The required parameter is null or empty.</exception>
        Public Sub SendMail(ByVal toList As List(Of String), ByVal ccList As List(Of String), ByVal bccList As List(Of String), ByVal subject As String, ByVal messageBody As String, ByVal attachmentList As List(Of String))
            ' Check if user has already logged on.
            If Not Me.isLoggedOn Then
                Throw New MapiManagerException(MAPIResource.NotAvailableMapiSession)
            End If

            ' Check if toList, ccList and bccList all are null or empty.
            Dim ok As Boolean = False

            If toList IsNot Nothing Then
                If toList.Count <> 0 Then
                    ok = True
                End If
            End If

            If ccList IsNot Nothing Then
                If ccList.Count <> 0 Then
                    ok = True
                End If
            End If

            If bccList IsNot Nothing Then
                If bccList.Count <> 0 Then
                    ok = True
                End If
            End If

            If ok = False Then
                Throw New ArgumentNullException(MAPIResource.ParametersToListCcListBccList)
            End If

            Dim sendMessage As New MapiManagementNative.MapiMessage()

            ' Set properties of mail to be sent.
            sendMessage.subject = subject
            sendMessage.messageBody = messageBody

            ' Add recipients of mail.
            AddReceipent(toList, "To")
            AddReceipent(ccList, "Cc")
            AddReceipent(bccList, "Bcc")

            ' Add attachement files' path.
            AttachFile(attachmentList)

            Try
                ' set pointers.
                sendMessage.originator = GetPointerToOriginator()
                sendMessage.recipients = GetPointerToRecipients(sendMessage.recipientCount)
                sendMessage.files = GetPointerToAttachments(sendMessage.fileCount)

                ' Send mail.
                Dim result As MAPIResult = CType(MapiManagementNative.MAPISendMail(mapiSession, IntPtr.Zero, sendMessage, 0, 0), MAPIResult)

                ' Deallocate pointers.
                DeallocatePointers(sendMessage)
                sendMessage = Nothing
                If result <> MAPIResult.Success Then
                    Throw New MapiManagerException(result.ToString())
                End If
            Catch exception As Exception
                Throw New MapiManagerException(exception.Message)
            End Try
        End Sub



#End Region

#Region "Use of managed System.Net.Mail"
        ''' <summary>
        ''' Creates credentials to send mail through specified mail account.
        ''' </summary>
        ''' <param name="userName">Name of user's mail account through which mail is to be sent.</param>
        ''' <param name="password">Password of specified user's mail account.</param>
        ''' <param name="host">A System.String that contains the name or IP address of the host used for
        ''' SMTP transactions.</param>
        ''' <param name="port">An System.Int32 greater than zero that contains the port to be used on host. </param>
        Public Sub CreateCredentialsToSendMail(ByVal userName As String, ByVal password As String, ByVal host As String, ByVal port As Integer)

            If (String.IsNullOrEmpty(userName)) Then
                Throw New ArgumentNullException(MAPIResource.ParameterUsername)
            End If

            If (String.IsNullOrEmpty(password)) Then
                Throw New ArgumentNullException(MAPIResource.ParameterPassword)
            End If

            If (String.IsNullOrEmpty(host)) Then
                Throw New ArgumentNullException(MAPIResource.ParamaterHost)
            End If

            If (port < 0) Then
                Throw New ArgumentException(MAPIResource.ParameterPort)
            End If

            Try
                Me.smtpClient = New SmtpClient(host, port)
                Me.smtpClient.EnableSsl = True
                Me.smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network
                Me.smtpClient.UseDefaultCredentials = False
                Me.smtpClient.Credentials = New System.Net.NetworkCredential(userName, password)

            Catch exception As Exception
                Me.smtpClient = Nothing
                Throw New MapiManagerException(exception.Message)
            End Try
        End Sub

        ''' <summary>
        ''' Send a mail to the specified receivers specified through SMTP server.
        ''' </summary>
        ''' <param name="mail">Object of Mail class.</param>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        ''' <exception cref="ArgumentNullException">The required parameter is nothing or empty.</exception>
        Public Sub SendMailThroughSMTPServer(ByVal mail As Mail)
            ' Check if mailTobeSent is nothing.
            If (mail Is Nothing) Then
                Throw New ArgumentNullException(MAPIResource.ParameterMailTobeSent)
            Else
                ' Check if user has already logged on.
                If (Me.smtpClient Is Nothing) Then
                    Throw New MapiManagerException(MAPIResource.CredentialNotCreated)
                End If

                If (String.IsNullOrEmpty(mail.From)) Then
                    Throw New InvalidOperationException(MAPIResource.MustFromAddress)
                End If

                Try

                    ' Create an instance of MailMessage class to set properties of mail to be sent.
                    Dim messageTobeSent As MailMessage = New MailMessage()

                    Dim index As Integer

                    If (mail.BccList IsNot Nothing) Then

                        For index = 0 To mail.BccList.Count - 1 Step 1
                            messageTobeSent.Bcc.Add(New MailAddress(mail.BccList(index)))
                        Next
                    End If

                    If (mail.CcList IsNot Nothing) Then

                        For index = 0 To mail.CcList.Count - 1 Step 1
                            messageTobeSent.CC.Add(New MailAddress(mail.CcList(index)))
                        Next
                    End If

                    If (mail.ToList IsNot Nothing) Then

                        For index = 0 To mail.ToList.Count - 1 Step 1

                            messageTobeSent.To.Add(New MailAddress(mail.ToList(index)))
                        Next
                    End If

                    If (mail.Attachments IsNot Nothing) Then

                        For index = 0 To mail.Attachments.Count - 1 Step 1

                            messageTobeSent.Attachments.Add(New Attachment(mail.Attachments(index)))
                        Next
                    End If

                    ' Set BodyEncoding for message to be sent as per passed value of Encoding enumeration.
                    Select Case (mail.BodyEncoding)

                        Case EncodingOptions.ASCII
                            messageTobeSent.BodyEncoding = System.Text.Encoding.ASCII

                        Case EncodingOptions.BigEndianUnicode
                            messageTobeSent.BodyEncoding = System.Text.Encoding.BigEndianUnicode

                        Case EncodingOptions.Default
                            messageTobeSent.BodyEncoding = System.Text.Encoding.Default

                        Case EncodingOptions.Unicode
                            messageTobeSent.BodyEncoding = System.Text.Encoding.Unicode

                        Case EncodingOptions.UTF32
                            messageTobeSent.BodyEncoding = System.Text.Encoding.UTF32

                        Case EncodingOptions.UTF7
                            messageTobeSent.BodyEncoding = System.Text.Encoding.UTF7

                        Case EncodingOptions.UTF8
                            messageTobeSent.BodyEncoding = System.Text.Encoding.UTF8

                    End Select

                    messageTobeSent.Body = mail.MessageBody

                    If (Not (String.IsNullOrEmpty(mail.From))) Then
                        messageTobeSent.From = New MailAddress(mail.From)
                    End If

                    messageTobeSent.Subject = mail.Subject

                    messageTobeSent.DeliveryNotificationOptions = CType((CType(mail.DeliveryNotificationOptions, Integer)), System.Net.Mail.DeliveryNotificationOptions)

                    messageTobeSent.IsBodyHtml = mail.IsBodyHtml

                    messageTobeSent.Priority = CType(CType(mail.Priority, Integer), MailPriority)

                    If (Not (String.IsNullOrEmpty(mail.ReplyTo))) Then
                        messageTobeSent.ReplyTo = New MailAddress(mail.ReplyTo)
                    End If

                    If (Not (String.IsNullOrEmpty(mail.Sender))) Then
                        messageTobeSent.Sender = New MailAddress(mail.Sender)
                    End If

                    ' Set SubjectEncoding for message to be sent as per passed value of Encoding enumeration.
                    Select Case (mail.SubjectEncoding)
                        Case EncodingOptions.ASCII
                            messageTobeSent.SubjectEncoding = System.Text.Encoding.ASCII

                        Case EncodingOptions.BigEndianUnicode
                            messageTobeSent.SubjectEncoding = System.Text.Encoding.BigEndianUnicode

                        Case EncodingOptions.Default
                            messageTobeSent.SubjectEncoding = System.Text.Encoding.Default

                        Case EncodingOptions.Unicode
                            messageTobeSent.SubjectEncoding = System.Text.Encoding.Unicode

                        Case EncodingOptions.UTF32
                            messageTobeSent.SubjectEncoding = System.Text.Encoding.UTF32

                        Case EncodingOptions.UTF7
                            messageTobeSent.SubjectEncoding = System.Text.Encoding.UTF7

                        Case EncodingOptions.UTF8
                            messageTobeSent.SubjectEncoding = System.Text.Encoding.UTF8

                    End Select
                    ' Create and add Alternate view as per specified through AlternateViews enumeration.
                    Select Case mail.AlternateViews
                        Case AlternateBodyViews.Html
                            messageTobeSent.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(mail.MessageBody, messageTobeSent.BodyEncoding, MediaTypeNames.Text.Html))

                        Case AlternateBodyViews.Plain
                            messageTobeSent.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(mail.MessageBody, messageTobeSent.BodyEncoding, MediaTypeNames.Text.Plain))

                        Case AlternateBodyViews.RichText
                            messageTobeSent.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(mail.MessageBody, messageTobeSent.BodyEncoding, MediaTypeNames.Text.RichText))

                        Case AlternateBodyViews.Xml
                            messageTobeSent.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(mail.MessageBody, messageTobeSent.BodyEncoding, MediaTypeNames.Text.Xml))
                    End Select

                    ' Send mail.
                    smtpClient.Send(messageTobeSent)

                Catch exception As Exception
                    Throw New MapiManagerException(exception.Message)
                End Try
            End If
        End Sub

        ''' <summary>
        ''' Send a mail to the specified receivers specified through SMTP server.
        ''' </summary>
        ''' <param name="toList">List of receivers who should be in ‘To’ list.</param>
        ''' <param name="subject">Subject line of the mail.</param>
        ''' <param name="from">Address of the sender of the e-mail message.</param>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        ''' <exception cref="ArgumentNullException">The required parameter is nothing or empty.</exception>
        Public Sub SendMailThroughSMTPServer(ByVal toList As List(Of String), ByVal subject As String, ByVal [from] As String)
            ' Send mail.
            SendMailThroughSMTPServer(toList, Nothing, Nothing, subject, String.Empty, Nothing, [from])
        End Sub

        ''' <summary>
        ''' Send a mail to the specified receivers specified through SMTP server.
        ''' </summary>
        ''' <param name="toList">List of receivers who should be in ‘To’ list.</param>
        ''' <param name="subject">Subject line of the mail.</param>
        ''' <param name="messageBody">Content of the mail body.</param>
        ''' <param name="from">Address of the sender of the e-mail message.</param>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        ''' <exception cref="ArgumentNullException">The required parameter is nothing or empty.</exception>
        Public Sub SendMailThroughSMTPServer(ByVal toList As List(Of String), ByVal subject As String, ByVal messageBody As String, ByVal [from] As String)
            ' Send mail.
            SendMailThroughSMTPServer(toList, Nothing, Nothing, subject, messageBody, Nothing, [from])
        End Sub

        ''' <summary>
        ''' Send a mail to the specified receivers specified through SMTP server.
        ''' </summary>
        ''' <param name="toList">List of receivers who should be in ‘To’ list.</param>
        ''' <param name="subject">Subject line of the mail.</param>
        ''' <param name="messageBody">Content of the mail body.</param>
        ''' <param name="from">Address of the sender of the e-mail message.</param>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        ''' <exception cref="ArgumentNullException">The required parameter is nothing or empty.</exception>
        Public Sub SendMailThroughSMTPServer(ByVal toList As List(Of String), ByVal subject As String, ByVal messageBody As String, ByVal attachmentList As List(Of String), ByVal [from] As String)
            ' Send mail.
            SendMailThroughSMTPServer(toList, Nothing, Nothing, subject, messageBody, attachmentList, [from])
        End Sub

        ''' <summary>
        ''' Send a mail to the specified receivers specified through SMTP server.
        ''' </summary>
        ''' <param name="toList">List of receivers who should be in ‘To’ list.</param>
        ''' <param name="ccList">List of receivers who should be in ‘Cc’ list.</param>
        ''' <param name="subject">Subject line of the mail.</param>
        ''' <param name="messageBody">Content of the mail body.</param>
        ''' <param name="from">Address of the sender of the e-mail message.</param>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        ''' <exception cref="ArgumentNullException">The required parameter is nothing or empty.</exception>
        Public Sub SendMailThroughSMTPServer(ByVal toList As List(Of String), ByVal ccList As List(Of String), ByVal subject As String, ByVal messageBody As String, ByVal [from] As String)
            ' Send mail.
            SendMailThroughSMTPServer(toList, ccList, Nothing, subject, messageBody, Nothing, [from])
        End Sub

        ''' <summary>
        ''' Send a mail to the specified receivers specified through SMTP server.
        ''' </summary>
        ''' <param name="toList">List of receivers who should be in ‘To’ list.</param>
        ''' <param name="ccList">List of receivers who should be in ‘Cc’ list.</param>
        ''' <param name="bccList">List of receivers who should be in ‘Bcc’ list.</param>
        ''' <param name="subject">Subject line of the mail.</param>
        ''' <param name="messageBody">Content of the mail body.</param>  
        ''' <param name="from">Address of the sender of the e-mail message.</param>
        ''' <param name="attachmentList">List of paths of the files to be attached with the mail.</param>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        ''' <exception cref="ArgumentNullException">The required parameter is nothing or empty.</exception>
        Public Sub SendMailThroughSMTPServer(ByVal toList As List(Of String), ByVal ccList As List(Of String), ByVal bccList As List(Of String), ByVal subject As String, ByVal messageBody As String, ByVal attachmentList As List(Of String), ByVal [from] As String)
            If (Me.smtpClient Is Nothing) Then
                Throw New MapiManagerException(MAPIResource.CredentialNotCreated)
            End If

            If (String.IsNullOrEmpty([from])) Then
                Throw New InvalidOperationException(MAPIResource.MustFromAddress)
            End If

            Try

                ' Create an instance of MailMessage class to set properties of mail to be sent.
                Dim messageTobeSent As MailMessage = New MailMessage()

                Dim index As Integer

                If (bccList IsNot Nothing) Then

                    For index = 0 To bccList.Count - 1 Step 1
                        messageTobeSent.Bcc.Add(New MailAddress(bccList(index)))
                    Next
                End If

                If (ccList IsNot Nothing) Then

                    For index = 0 To ccList.Count - 1 Step 1
                        messageTobeSent.CC.Add(New MailAddress(ccList(index)))
                    Next
                End If

                If (toList IsNot Nothing) Then

                    For index = 0 To toList.Count - 1 Step 1

                        messageTobeSent.To.Add(New MailAddress(toList(index)))
                    Next
                End If

                If (attachmentList IsNot Nothing) Then

                    For index = 0 To attachmentList.Count - 1 Step 1

                        messageTobeSent.Attachments.Add(New Attachment(attachmentList(index)))
                    Next
                End If


                messageTobeSent.Body = messageBody

                If (Not (String.IsNullOrEmpty([from]))) Then

                    messageTobeSent.From = New MailAddress([from])
                End If

                messageTobeSent.Subject = subject

                ' Send mail.
                smtpClient.Send(messageTobeSent)


            Catch exception As Exception
                Throw New MapiManagerException(exception.Message, exception.InnerException)
            End Try
        End Sub

#End Region

#End Region

#Region "GetMails"

        ''' <summary>
        ''' Retrieves all available mails from Inbox.
        ''' </summary>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        ''' <returns>List of available mails from inbox.</returns>
        Public Function GetAvailableMails() As List(Of Mail)
            ' Get available mails from Inbox.
            Dim mailList As List(Of Mail) = Me.GetAvailableMails(MapiLongMsgID)
            Return mailList
        End Function

        ''' <summary>
        ''' Retrieves all unread mails from Inbox.
        ''' </summary>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        ''' <returns>List of available unread mails from inbox.</returns>

        Public Function GetUnreadMails() As List(Of Mail)
            ' Get unread available mails.
            Dim resultMailList As List(Of Mail) = Me.GetAvailableMails(MapiUnreadOnly)
            Return resultMailList
        End Function

#End Region

#Region "SaveAttchments"

        ''' <summary>
        ''' Save the specified attachment at the specified location.
        ''' </summary>
        ''' <param name="mailId">Id of the mail whose attachment is to be saved.</param>
        ''' <param name="attachmentName">Name of the attachment to be saved. This name follows tilde sign notations, because of API limitations.</param>
        ''' <param name="targetLocation">Location where attachment is to be saved.</param>
        ''' <param name="saveAsName">Name of attachment to be saved as.</param>
        ''' <param name="forceSave">If true then it overwrites the existing file.</param>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        ''' <exception cref="ArgumentNullException">The required parameter is null or empty.</exception>
        ''' <exception cref="ArgumentException">The specified parameter is not valid.</exception>
        Public Sub SaveAttachment(ByVal mailId As String, ByVal attachmentName As String, ByVal targetLocation As String, ByVal saveAsName As String, ByVal forceSave As Boolean)
            ' Check if user has already logged on.
            If Not Me.isLoggedOn Then
                Throw New MapiManagerException(MAPIResource.NotAvailableMapiSession)
            End If

            ' Check if any of passed parameters are null or empty.
            If String.IsNullOrEmpty(mailId) Then
                Throw New ArgumentNullException(MAPIResource.ParameterMailId)
            ElseIf String.IsNullOrEmpty(targetLocation) Then
                Throw New ArgumentNullException(MAPIResource.PatameterTargetLocation)
            ElseIf String.IsNullOrEmpty(saveAsName) Then
                Throw New ArgumentNullException(MAPIResource.ParamaterSaveAsName)
            End If

            Dim filePath As String = targetLocation

            ' Concat "\\" to path if not in target location.
            If Not filePath.EndsWith(MAPIResource.Backslashes) Then
                filePath = String.Concat(filePath, MAPIResource.Backslashes)
            End If

            ' Check specified directory exist or not.
            If Not Directory.Exists(filePath) Then
                Throw New ArgumentException(MAPIResource.DirectoryNotExist)
            End If

            targetLocation = filePath

            Dim attachmentFound As Boolean = False
            Dim maxLengthFileName As Boolean = False
            Try
                Dim result As MAPIResult
                Dim ptrToMessage As IntPtr = IntPtr.Zero

                ' Read specified mail.
                result = CType(MapiManagementNative.MAPIReadMail(mapiSession, IntPtr.Zero, mailId, MapiPeek, 0, ptrToMessage), MAPIResult)

                If Not ((result <> MAPIResult.Success) OrElse (ptrToMessage = IntPtr.Zero)) Then
                    Dim fetchedMessage As New MapiManagementNative.MapiMessage()
                    Marshal.PtrToStructure(ptrToMessage, fetchedMessage)

                    ' Check if read mail has attachments.
                    If (fetchedMessage.fileCount > 0) AndAlso (fetchedMessage.fileCount < 100) AndAlso (fetchedMessage.files <> IntPtr.Zero) Then
                        Dim fileDescriptionSize As Integer = Marshal.SizeOf(GetType(MapiManagementNative.MapiFileDesc))
                        Dim fileDescription As New MapiManagementNative.MapiFileDesc()
                        Dim incrementPtr As Integer = CInt(fetchedMessage.files)

                        For i As Integer = 0 To fetchedMessage.fileCount - 1

                            ' Check for specified attachement in list of attachments.
                            filePath = targetLocation
                            Marshal.PtrToStructure(CType(incrementPtr, IntPtr), fileDescription)
                            incrementPtr += fileDescriptionSize
                            If fileDescription.flags <> 0 Then
                                Continue For
                            End If
                            If String.IsNullOrEmpty(fileDescription.fileName) Then
                                Continue For
                            End If

                            ' Get qualified name of attachment to be saved as.
                            filePath = String.Concat(filePath, saveAsName)

                            If [String].Compare(attachmentName, fileDescription.fileName, True) = 0 Then
                                attachmentFound = True

                                ' Check if attachment already exist at specified target location.
                                If File.Exists(filePath) Then
                                    If forceSave Then
                                        File.Delete(filePath)
                                    Else
                                        Continue For
                                    End If
                                End If
                                ' Check for maximum length of qualified name of file.
                                If filePath.Length > 258 Then
                                    maxLengthFileName = True
                                    Exit For
                                End If

                                ' Save file at specified target location.
                                File.Copy(fileDescription.pathName, filePath)

                                ' Delete temporary file.
                                File.Delete(fileDescription.pathName)
                                Exit For
                            End If
                        Next
                    End If
                    MapiManagementNative.MAPIFreeBuffer(ptrToMessage)
                Else
                    Throw New MapiManagerException(result.ToString())
                End If
            Catch exception As Exception
                Throw New MapiManagerException(exception.Message)
            End Try

            If maxLengthFileName Then
                Throw New ArgumentException(MAPIResource.SaveasNameMaxLength)
            End If

            If Not attachmentFound Then
                Throw New ArgumentException(MAPIResource.AttachementNotFound)
            End If
        End Sub

        ''' <summary>
        ''' Save the specified attachment at the specified location.
        ''' </summary>
        ''' <param name="mailId">Id of the mail whose attachment is to be saved.</param>
        ''' <param name="attachmentPosition">Position of the attachment in the mail.
        '''  E.g. 1 for 1st attachment and so on.</param>
        ''' <param name="targetLocation">Location where the attachment is to be saved.</param>
        ''' <param name="saveAsName">Name of attachment to be saved as.</param>
        ''' <param name="forceSave">If true then it overwrites the existing file.</param>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        ''' <exception cref="ArgumentNullException">The required parameter is null or empty.</exception>
        ''' <exception cref="ArgumentException">The specified parameter is not valid.</exception>
        Public Sub SaveAttachment(ByVal mailId As String, ByVal attachmentPosition As Integer, ByVal targetLocation As String, ByVal saveAsName As String, ByVal forceSave As Boolean)
            ' Check any of passed parameters are null or empty.
            If String.IsNullOrEmpty(mailId) Then
                Throw New ArgumentNullException(MAPIResource.ParameterMailId)
            ElseIf attachmentPosition < 0 Then
                Throw New ArgumentException(MAPIResource.ParameterAttachmentPosistion)
            ElseIf String.IsNullOrEmpty(targetLocation) Then
                Throw New ArgumentNullException(MAPIResource.PatameterTargetLocation)
            ElseIf String.IsNullOrEmpty(saveAsName) Then
                Throw New ArgumentNullException(MAPIResource.ParamaterSaveAsName)
            End If

            ' Check if user has already logged on.
            If Not Me.isLoggedOn Then
                Throw New MapiManagerException(MAPIResource.NotAvailableMapiSession)
            End If

            Dim filePath As String = targetLocation

            ' Concat "\\" to path if not in target location.
            If Not filePath.EndsWith(MAPIResource.Backslashes) Then
                filePath = String.Concat(filePath, MAPIResource.Backslashes)
            End If

            ' Check specified directory exist or not.
            If Not Directory.Exists(filePath) Then
                Throw New ArgumentException(MAPIResource.DirectoryNotExist)
            End If

            targetLocation = filePath

            Dim attachmentFound As Boolean = False
            Dim maxLengthFileName As Boolean = False
            Try
                Dim result As MAPIResult
                Dim ptrToMessage As IntPtr = IntPtr.Zero

                ' Read specified mail.
                result = CType(MapiManagementNative.MAPIReadMail(mapiSession, IntPtr.Zero, mailId, MapiPeek, 0, ptrToMessage), MAPIResult)


                If Not ((result <> MAPIResult.Success) OrElse (ptrToMessage = IntPtr.Zero)) Then
                    Dim fetchedMessage As New MapiManagementNative.MapiMessage()
                    Marshal.PtrToStructure(ptrToMessage, fetchedMessage)

                    ' Check if read mail has attachments.
                    If (fetchedMessage.fileCount > 0) AndAlso (fetchedMessage.fileCount < 100) AndAlso (fetchedMessage.files <> IntPtr.Zero) Then
                        Dim fileDescriptionSize As Integer = Marshal.SizeOf(GetType(MapiManagementNative.MapiFileDesc))
                        Dim fileDescription As New MapiManagementNative.MapiFileDesc()
                        Dim incrementPtr As Integer = CInt(fetchedMessage.files)

                        For index As Integer = 0 To fetchedMessage.fileCount - 1

                            ' Check for specified attachement in list of attachments.
                            filePath = targetLocation
                            Marshal.PtrToStructure(CType(incrementPtr, IntPtr), fileDescription)
                            incrementPtr += fileDescriptionSize

                            If fileDescription.flags <> 0 Then
                                Continue For
                            End If
                            If String.IsNullOrEmpty(fileDescription.fileName) Then
                                Continue For
                            End If

                            ' Get qualified name of attachment to be saved as.
                            filePath = String.Concat(filePath, saveAsName)

                            If index = attachmentPosition Then
                                attachmentFound = True

                                ' Check if attachment already exist at specified target location.
                                If File.Exists(filePath) Then
                                    If forceSave Then
                                        File.Delete(filePath)
                                    Else
                                        Continue For
                                    End If
                                End If

                                ' Check for maximum length of qualified name of file.
                                If filePath.Length > 258 Then
                                    maxLengthFileName = True
                                    Exit For
                                End If

                                ' Save file at specified target location.
                                File.Copy(fileDescription.pathName, filePath)

                                ' Delete temporary file.
                                File.Delete(fileDescription.pathName)
                                Exit For
                            End If
                        Next
                    End If
                    MapiManagementNative.MAPIFreeBuffer(ptrToMessage)
                Else
                    Throw New MapiManagerException(result.ToString())
                End If
            Catch exception As Exception
                Throw New MapiManagerException(exception.Message)
            End Try

            If maxLengthFileName Then
                Throw New ArgumentException(MAPIResource.SaveasNameMaxLength)
            End If

            If Not attachmentFound Then
                Throw New ArgumentException(MAPIResource.AttachementNotFound)
            End If

        End Sub

        ''' <summary>
        '''  Saves all the attachments of the specified mail at specified location. 
        ''' All attachments are saved with attachment name specified in mail. 
        ''' Names of saved attachments follow tilde sign notations, because of API limitations.
        ''' </summary>
        ''' <param name="mailId">Id of the mail whose attachments are to be saved.</param>
        ''' <param name="targetLocation">Location where the attachment is to be saved.</param>
        ''' <param name="forceSave">If true then it overwrites the existing file.</param>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        ''' <exception cref="ArgumentNullException">The required parameter is null or empty.</exception>
        ''' <exception cref="ArgumentException">The specified parameter is not valid.</exception>
        ''' <returns>Number of attachments saved.</returns>
        Public Function SaveAllAttachments(ByVal mailId As String, ByVal targetLocation As String, ByVal forceSave As Boolean) As Integer
            ' Check any of passed parameters are null or empty.
            If Not Me.isLoggedOn Then
                Throw New MapiManagerException(MAPIResource.NotAvailableMapiSession)
            End If

            ' Check any of passed parameters are null or empty.
            If String.IsNullOrEmpty(mailId) Then
                Throw New ArgumentNullException(MAPIResource.ParameterMailId)
            ElseIf String.IsNullOrEmpty(targetLocation) Then
                Throw New ArgumentNullException(MAPIResource.PatameterTargetLocation)
            End If

            Dim filePath As String = targetLocation

            ' Concat "\\" to path if not in target location.
            If Not filePath.EndsWith(MAPIResource.Backslashes) Then
                filePath = String.Concat(filePath, MAPIResource.Backslashes)
            End If

            ' Check specified directory exist or not.
            If Not Directory.Exists(filePath) Then
                Throw New ArgumentException(MAPIResource.DirectoryNotExist)
            End If

            targetLocation = filePath

            Dim countFilesSaved As Integer = 0
            Try
                Dim result As MAPIResult
                Dim ptrToMessage As IntPtr = IntPtr.Zero

                ' Read specified mail.
                result = CType(MapiManagementNative.MAPIReadMail(mapiSession, IntPtr.Zero, mailId, MapiPeek, 0, ptrToMessage), MAPIResult)

                If Not ((result <> MAPIResult.Success) OrElse (ptrToMessage = IntPtr.Zero)) Then
                    Dim fetchedMessage As New MapiManagementNative.MapiMessage()
                    Marshal.PtrToStructure(ptrToMessage, fetchedMessage)

                    ' Check if read mail has attachments.
                    If (fetchedMessage.fileCount > 0) AndAlso (fetchedMessage.fileCount < 100) AndAlso (fetchedMessage.files <> IntPtr.Zero) Then
                        Dim fileDescriptionSize As Integer = Marshal.SizeOf(GetType(MapiManagementNative.MapiFileDesc))
                        Dim fileDescription As New MapiManagementNative.MapiFileDesc()
                        Dim incrementPtr As Integer = CInt(fetchedMessage.files)

                        For i As Integer = 0 To fetchedMessage.fileCount - 1

                            ' Check for specified attachement in list of attachments.
                            filePath = targetLocation
                            Marshal.PtrToStructure(CType(incrementPtr, IntPtr), fileDescription)
                            incrementPtr += fileDescriptionSize
                            If fileDescription.flags <> 0 Then
                                Continue For
                            End If
                            If String.IsNullOrEmpty(fileDescription.fileName) Then
                                Continue For
                            End If

                            ' Get qualified name of attachment to be saved.
                            filePath = String.Concat(filePath, fileDescription.fileName)

                            ' Check if attachment already exist at specified target location.
                            If File.Exists(filePath) Then
                                If forceSave Then
                                    File.Delete(filePath)
                                Else
                                    Continue For
                                End If
                            End If

                            ' Save file at specified target location.
                            File.Copy(fileDescription.pathName, filePath)

                            ' Increment count of files saved.
                            countFilesSaved += 1

                            ' Delete temporary file.
                            File.Delete(fileDescription.pathName)
                        Next
                    End If
                    MapiManagementNative.MAPIFreeBuffer(ptrToMessage)
                Else
                    Throw New MapiManagerException(result.ToString())

                End If
            Catch exception As Exception
                If exception.Message = MAPIResource.InvalidMessage Then
                    Throw New ArgumentException(MAPIResource.InvalidmailId)
                Else
                    Throw New MapiManagerException(exception.Message)
                End If
            End Try
            Return countFilesSaved
        End Function

#End Region

        ''' <summary>
        ''' Ends a session with the messaging system.
        ''' </summary>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        ''' <exception cref="InvalidOperationException">This exception is raised when there is no MAPI session to end.</exception>
        Public Sub Logoff()
            ' Check user has logged on or not.
            If Me.isLoggedOn Then
                Me.isLoggedOn = False
            Else
                Throw New InvalidOperationException(MAPIResource.AgainLogoff)
            End If

            Dim result As MAPIResult = MAPIResult.Success
            Try
                If mapiSession <> IntPtr.Zero Then
                    ' Log off from profile.
                    result = CType(MapiManagementNative.MAPILogoff(mapiSession, IntPtr.Zero, 0, 0), MAPIResult)
                    mapiSession = IntPtr.Zero
                End If
                If result <> MAPIResult.Success Then
                    Throw New MapiManagerException(result.ToString())

                Else
                End If
            Catch exception As Exception
                Throw New MapiManagerException(exception.Message)
            End Try

        End Sub

        ''' <summary>
        ''' Deletes the specified mail from inbox.
        ''' </summary>
        ''' <param name="mailId">Id of mail to be deleted.</param>
        ''' <exception cref="ArgumentNullException">The required parameter is null or empty.</exception>
        ''' <exception cref="ArgumentException">The specified parameter is not valid.</exception>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        Public Sub DeleteMail(ByVal mailId As String)
            ' Check mailId is null or empty.
            If String.IsNullOrEmpty(mailId) Then
                Throw New ArgumentNullException(MAPIResource.ParameterMailId)
            End If
            Try
                ' Delete specified mail.
                Dim result As MAPIResult = CType(MapiManagementNative.MAPIDeleteMail(mapiSession, IntPtr.Zero, mailId, 0, 0), MAPIResult)
                If result <> MAPIResult.Success Then
                    Throw New MapiManagerException(result.ToString())
                End If
            Catch exception As Exception
                If exception.Message = MAPIResource.InvalidMessage Then
                    Throw New ArgumentException(MAPIResource.InvalidmailId)
                Else
                    Throw New MapiManagerException(exception.Message)
                End If
            End Try
        End Sub

#End Region

#Region "Public methods - Profile"

        ''' <summary>
        ''' Creates a new profile with the specified name.
        ''' </summary>
        ''' <param name="profileName">Name of the new profile to be created.</param>
        ''' <exception cref="ArgumentNullException">The required parameter is null or empty.</exception>
        ''' <exception cref="ArgumentException">The specified parameter is not valid.</exception>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        Public Sub CreateNewProfile(ByVal profileName As String)
            ' Check profileName is null or empty.
            If String.IsNullOrEmpty(profileName) Then
                Throw New ArgumentNullException(MAPIResource.ParameterProfileName)
            End If

            ' Check maximum length of specified profileName.
            If profileName.Length > 64 Then
                Throw New ArgumentException(MAPIResource.MaxProfileNameLength)
            End If
            Try
                If profileAdmin IsNot Nothing Then
                    Dim result As MAPIResult

                    ' Create profile.
                    result = CType(profileAdmin.CreateProfile(Marshal.StringToHGlobalAnsi(profileName), IntPtr.Zero, IntPtr.Zero, CInt(MapiFlags.Dialog)), MAPIResult)

                    If result <> MAPIResult.Success Then
                        Throw New MapiManagerException(result.ToString())
                    End If
                End If
            Catch exception As Exception
                If exception.Message = MAPIResource.ErrorNoAccess Then
                    Throw New ArgumentException(MAPIResource.ProfileExist)
                End If
                Throw New MapiManagerException(exception.Message)
            End Try

        End Sub

        ''' <summary>
        ''' Deletes specified profile.
        ''' </summary>
        ''' <param name="profileName">Name of profile to be deleted.</param>
        ''' <exception cref="ArgumentNullException">The required parameter is null or empty.</exception>
        ''' <exception cref="ArgumentException">The specified parameter is not valid.</exception>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        Public Sub DeleteProfile(ByVal profileName As String)
            ' Check profileName is null or empty.
            If String.IsNullOrEmpty(profileName) Then
                Throw New ArgumentNullException(MAPIResource.ParameterProfileName)
            End If

            Try
                If profileAdmin IsNot Nothing Then
                    Dim result As MAPIResult

                    ' Delete profile.
                    result = CType(profileAdmin.DeleteProfile(Marshal.StringToHGlobalAnsi(profileName), CInt(MapiFlags.[Default])), MAPIResult)

                    If result <> MAPIResult.Success Then
                        Throw New MapiManagerException(result.ToString())
                    End If
                End If
            Catch exception As Exception
                If exception.Message = MAPIResource.ErrorNotFound Then
                    Throw New ArgumentException(MAPIResource.ProfileNotExist)
                Else
                    Throw New MapiManagerException(exception.Message)
                End If
            End Try
        End Sub

        ''' <summary>
        ''' Sets the specified profile as the default profile.
        ''' </summary>
        ''' <param name="profileName">Name of profile to be set as the default profile.</param>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        ''' <exception cref="ArgumentNullException">The required parameter is null or empty.</exception>
        ''' <exception cref="ArgumentException">The specified parameter is not valid.</exception>
        Public Sub SetDefaultProfile(ByVal profileName As String)
            ' Check profileName is null or empty.
            If String.IsNullOrEmpty(profileName) Then
                Throw New ArgumentNullException(MAPIResource.ParameterProfileName)
            End If
            Try
                If profileAdmin IsNot Nothing Then
                    Dim result As MAPIResult

                    ' Set default profile.
                    result = CType(profileAdmin.SetDefaultProfile(Marshal.StringToHGlobalAnsi(profileName), CInt(MapiFlags.[Default])), MAPIResult)

                    If result <> MAPIResult.Success Then
                        Throw New MapiManagerException(result.ToString())
                    End If
                End If
            Catch exception As Exception
                If exception.Message = MAPIResource.ErrorNotFound Then
                    Throw New ArgumentException(MAPIResource.ProfileNotExist)
                Else
                    Throw New MapiManagerException(exception.Message)
                End If
            End Try
        End Sub

        ''' <summary>
        ''' Renames specified profile.
        ''' </summary>
        ''' <param name="oldProfileName">Name of the profile to be renamed.</param>
        ''' <param name="newProfileName">New profile name.</param>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        ''' <exception cref="ArgumentNullException">The required parameter is null or empty.</exception>
        ''' <exception cref="ArgumentException">The specified parameter is not valid.</exception>
        Public Sub RenameProfile(ByVal oldProfileName As String, ByVal newProfileName As String)
            ' Check any of passed parameters are null or empty.
            If String.IsNullOrEmpty(oldProfileName) Then
                Throw New ArgumentNullException(MAPIResource.ParameterOldProfileName)
            ElseIf String.IsNullOrEmpty(newProfileName) Then
                Throw New ArgumentNullException(MAPIResource.ParameterNewProfileName)
            End If

            ' Check for maximum length of newProfileName.
            If newProfileName.Length > 64 Then
                Throw New ArgumentException(MAPIResource.MaxProfileNameLength)
            End If

            '			#Region "Commented because of known issue of GetAvailableProfiles"
            '
            '			'List<string> profileList = this.GetAvailableProfiles();
            '			'if (!profileList.Contains(oldProfileName))
            '			'    throw new ArgumentException(MAPIResource.ProfileNotExist);
            '
            '			#End Region

            ' Check newProfileName and oldProfileName are equal or not.
            If oldProfileName.Equals(newProfileName) Then
                Throw New MapiManagerException(MAPIResource.SameProfileRename)
            End If
            Try
                If profileAdmin IsNot Nothing Then
                    Dim result As MAPIResult

                    ' Rename specified profile with new profile name.
                    result = CType(profileAdmin.RenameProfile(Marshal.StringToHGlobalAnsi(oldProfileName), IntPtr.Zero, Marshal.StringToHGlobalAnsi(newProfileName), IntPtr.Zero, CType(MapiFlags.[Default], IntPtr)), MAPIResult)

                    If result <> MAPIResult.Success Then
                        Throw New MapiManagerException(result.ToString())
                    End If
                End If
            Catch exception As Exception
                If exception.Message = MAPIResource.ErrorNotFound Then
                    Throw New ArgumentException(MAPIResource.ProfileNotExist)

                ElseIf exception.Message = MAPIResource.ErrorNoAccess Then
                    Throw New ArgumentException(MAPIResource.ProfileExist)
                Else
                    Throw (New MapiManagerException(exception.Message))
                End If
            End Try
        End Sub

        ''' <summary>
        ''' Copies specified profile in new profile.
        ''' </summary>
        ''' <param name="sourceProfileName">Name of the profile to be copied.</param>
        ''' <param name="destinationProfileName">Name of the new profile to be created.</param>
        ''' <exception cref="ArgumentNullException">The required parameter is null or empty.</exception>
        ''' <exception cref="ArgumentException">The specified parameter is not valid.</exception>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        Public Sub CopyProfile(ByVal sourceProfileName As String, ByVal destinationProfileName As String)
            ' Check any of passed parameters are null or empty.
            If String.IsNullOrEmpty(sourceProfileName) Then
                Throw New ArgumentNullException(MAPIResource.ParameterSourceProfileName)
            ElseIf String.IsNullOrEmpty(destinationProfileName) Then
                Throw New ArgumentNullException(MAPIResource.ParameterDestinationProfileName)
            End If

            ' Check for maximum length of newProfileName.
            If sourceProfileName.Length > 64 OrElse destinationProfileName.Length > 64 Then
                Throw New ArgumentException(MAPIResource.MaxProfileNameLength)
            End If

            Try
                If Not profileAdmin Is Nothing Then
                    Dim result As MAPIResult

                    ' Copy specified source profile into new destination profile.
                    result = CType(profileAdmin.CopyProfile(Marshal.StringToHGlobalAnsi(sourceProfileName), IntPtr.Zero, Marshal.StringToHGlobalAnsi(destinationProfileName), IntPtr.Zero, CType(MapiFlags.Default, IntPtr)), MAPIResult)

                    If result <> MAPIResult.Success Then
                        Throw New MapiManagerException(result.ToString())
                    End If

                End If
            Catch exception As Exception
                If exception.Message = MAPIResource.ErrorNotFound Then
                    Throw New ArgumentException(MAPIResource.ProfileNotExist)

                ElseIf exception.Message = MAPIResource.ErrorNoAccess Then
                    Throw New ArgumentException(MAPIResource.ProfileExist)
                Else
                    Throw (New MapiManagerException(exception.Message))
                End If
            End Try
        End Sub

        ''' <summary>
        ''' Gets all available profiles.
        ''' </summary>
        ''' <returns>List of available profiles.</returns>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        Public Function GetAvailableProfiles() As List(Of String)
            '/////////////////////////////////////////////////////////////////////////////
            ' Known issue: mapi32.dll is using union, which is not directly supported by c#.
            '////////////////////////////////////////////////////////////////////////////

            Dim resturnList As New List(Of String)()
            Try
                If profileAdmin IsNot Nothing Then
                    Dim result As MAPIResult

                    ' Get object of IMAPITable.
                    result = CType(profileAdmin.GetProfileTable(0, mapiTable), MAPIResult)

                    Dim count As UInteger
                    ' Get number of rows in table.
                    result = CType(mapiTable.GetRowCount(0, count), MAPIResult)
                    For index As Long = 0 To count - 1

                        Dim rowsetPtr As IntPtr
                        ' Query next row of table.
                        result = CType(mapiTable.QueryRows(1, 0, rowsetPtr), MAPIResult)

                        If result <> MAPIResult.Success Then
                            Throw New MapiManagerException(result.ToString())
                        End If

                        Dim obj As New MapiManagementNative.RowSet()
                        ' Get object of Rowset.
                        obj = DirectCast(Marshal.PtrToStructure(rowsetPtr, GetType(MapiManagementNative.RowSet)), MapiManagementNative.RowSet)

                        ' Add profilename in list to be returned.
                        resturnList.Add(obj.row(0).lpProps.Value.lpszW)

                        ' Destroy structure.
                        Marshal.DestroyStructure(rowsetPtr, GetType(MapiManagementNative.RowSet))
                    Next
                End If
            Catch exception As Exception
                Throw New MapiManagerException(exception.Message)
            End Try
            Return resturnList
        End Function

        ''' <summary>
        ''' Gets the name of the default profile.
        ''' </summary>
        ''' <exception cref="MapiManagerException">Call to native API has raised an error.</exception>
        Public Function GetDefaultProfile() As String
            Throw New System.NotImplementedException()

            '			#Region "Commented because of known issu of union"
            '
            '			'MAPIResult result;
            '
            '			'MapiManagementNative.PropValue spvDefaultProfile = new MapiManagementNative.PropValue();
            '
            '			'result = (MAPIResult)profileAdmin.GetProfileTable(0, out mapiTable);
            '
            '			'if (result == MAPIResult.Success)
            '			'{
            '			'    IntPtr rowsetPtr;
            '			'    result = (MAPIResult)mapiTable.QueryRows(1, 0, out rowsetPtr);
            '
            '			'    MapiManagementNative.RowSet obj;
            '			'    obj = (MapiManagementNative.RowSet)Marshal.PtrToStructure(rowsetPtr, typeof(MapiManagementNative.RowSet));
            '			'    return obj.row[0].lpProps.Value.lpszW;
            '			'}
            '			#End Region
        End Function
#End Region
    End Class

#Region "Public Classes"
    ''' <summary>
    ''' Contains information of mail.
    ''' </summary>
    <Designer(GetType(MapiSmartTagDesigner))> _
    <ToolboxItem(True), ToolboxBitmap(GetType(Mail))> _
 Public Class Mail
        Inherits Component
#Region "Private members"

        Friend m_date As DateTime
        Friend m_id As String
        Friend m_from As String
        Private m_subject As String
        Friend m_unread As Boolean
        Private m_messageBody As String
        Private m_attachments As List(Of String)
        Private m_toList As List(Of String)
        Private m_ccList As List(Of String)
        Friend m_bccList As List(Of String)

        ' Added for MailMessage
        Private m_alternateViews As AlternateBodyViews
        Private m_bodyEncoding As EncodingOptions
        Private m_deliveryNotificationOptions As DeliveryNotificationOptions
        Private m_isBodyHtml As Boolean
        Private m_priority As Priorities
        Private m_replyTo As String  ' Email Address
        Private m_sender As String  ' Email Address
        Private m_subjectEncoding As EncodingOptions

#End Region

#Region "Public properties"

        ''' <summary>
        ''' Id which uniquely identifies a mail.
        ''' </summary>
        Public ReadOnly Property Id() As String
            Get
                Return m_id
            End Get
        End Property

        ''' <summary>
        ''' Date when mail was received. 
        ''' </summary>
        Public ReadOnly Property [Date]() As DateTime
            Get
                Return m_date
            End Get
        End Property

        ''' <summary>
        ''' Id of the mails sender.
        ''' </summary>
        Public Property [From]() As String
            Get
                Return m_from
            End Get
            Set(ByVal value As String)
                m_from = value
            End Set
        End Property

        ''' <summary>
        ''' Subject of the mail.
        ''' </summary>
        Public Property Subject() As String
            Get
                Return m_subject
            End Get
            Set(ByVal value As String)
                m_subject = value
            End Set
        End Property

        ''' <summary>
        ''' Flag which indicates whether mail is already read or not.
        ''' </summary>
        Public ReadOnly Property Unread() As Boolean
            Get
                Return m_unread
            End Get
        End Property

        ''' <summary>
        ''' Body of the mail.
        ''' </summary>
        Public Property MessageBody() As String
            Get
                Return m_messageBody
            End Get
            Set(ByVal value As String)
                m_messageBody = value
            End Set
        End Property

        ''' <summary>
        ''' List of attachments in the mail.
        ''' </summary>
        <Editor(GetType(StringCollectionEditor), GetType(UITypeEditor))> _
        Public Property Attachments() As List(Of String)
            Get
                Return m_attachments
            End Get
            Set(ByVal value As List(Of String))
                m_attachments = value
            End Set
        End Property

        ''' <summary>
        ''' List of ids in the ‘To’ list.
        ''' </summary>
        <Editor(GetType(StringCollectionEditor), GetType(UITypeEditor))> _
        Public Property ToList() As List(Of String)
            Get
                Return m_toList
            End Get
            Set(ByVal value As List(Of String))
                m_toList = value
            End Set
        End Property

        ''' <summary>
        ''' List of ids in the ‘Cc’ list.
        ''' </summary>
        <Editor(GetType(StringCollectionEditor), GetType(UITypeEditor))> _
        Public Property CcList() As List(Of String)
            Get
                Return m_ccList
            End Get
            Set(ByVal value As List(Of String))
                m_ccList = value
            End Set
        End Property

        ''' <summary>
        ''' List of ids in the ‘Bcc’ list. This field is used only for sending mails.
        ''' This field will be empty for the received mails.
        ''' </summary>
        <Editor(GetType(StringCollectionEditor), GetType(UITypeEditor))> _
        Public Property BccList() As List(Of String)
            Get
                Return m_bccList
            End Get
            Set(ByVal value As List(Of String))
                m_bccList = value
            End Set
        End Property


        ''' <summary>
        ''' Gets or sets the priority of this e-mail message.
        ''' </summary>
        Public Property Priority() As Priorities
            Get
                Return m_priority
            End Get
            Set(ByVal value As Priorities)
                m_priority = value
            End Set
        End Property
        ''' <summary>
        ''' Gets or sets the encoding used for the subject content for this e-mail message.
        ''' </summary>
        Public Property SubjectEncoding() As EncodingOptions
            Get
                Return m_subjectEncoding
            End Get
            Set(ByVal value As EncodingOptions)
                m_subjectEncoding = value
            End Set
        End Property
        ''' <summary>
        ''' Gets or sets the ReplyTo address for the mail message.
        ''' </summary>
        Public Property ReplyTo() As String
            Get
                Return m_replyTo
            End Get
            Set(ByVal value As String)
                m_replyTo = value
            End Set
        End Property
        ''' <summary>
        ''' Gets or sets the sender's address for this e-mail message.
        ''' </summary>
        Public Property Sender() As String
            Get
                Return m_sender
            End Get
            Set(ByVal value As String)
                m_sender = value
            End Set
        End Property
        ''' <summary>
        ''' Gets or sets a value indicating whether the mail message body is in Html.
        ''' </summary>
        Public Property IsBodyHtml() As Boolean
            Get
                Return m_isBodyHtml
            End Get
            Set(ByVal value As Boolean)
                m_isBodyHtml = value
            End Set
        End Property
        ''' <summary>
        ''' Gets or sets the delivery notifications for this e-mail message.
        ''' </summary>
        Public Property DeliveryNotificationOptions() As DeliveryNotificationOptions
            Get
                Return m_deliveryNotificationOptions
            End Get
            Set(ByVal value As DeliveryNotificationOptions)
                m_deliveryNotificationOptions = value
            End Set
        End Property
        ''' <summary>
        ''' Gets or sets the encoding used to encode the message body.
        ''' </summary>
        Public Property BodyEncoding() As EncodingOptions
            Get
                Return m_bodyEncoding
            End Get
            Set(ByVal value As EncodingOptions)
                m_bodyEncoding = value
            End Set
        End Property
        ''' <summary>
        ''' Gets the attachment collection used to store alternate forms of the message body.
        ''' </summary>
        Public Property AlternateViews() As AlternateBodyViews
            Get
                Return m_alternateViews
            End Get
            Set(ByVal value As AlternateBodyViews)
                m_alternateViews = value
            End Set
        End Property

#End Region
    End Class
#End Region

#Region "Enumerations"

    ''' <summary>
    ''' Represents all possible results of MAPI operations.
    ''' </summary>
    Enum MAPIResult As Long
        AccessDenied = 6
        AccountDisabled = &H80040124
        AmbiguousRecip = &H80040700
        AmbiguousRecipient = &H15
        ApproxCount = &H40482
        AttachmentNotFound = 11
        AttachmentOpenFailure = 12
        AttachmentWriteFailure = 13
        BadCharWidth = &H80040103
        BadColumn = &H80040118
        BadRecipType = 15
        BadValue = &H80040301
        Busy = &H8004010B
        CallFailed = &H80004005
        Cancel = &H80040501
        CancelMessage = &H40580
        Collision = &H80040604
        Computed = &H8004011A
        CorruptData = &H8004011B
        CorruptStore = &H80040600
        DeclineCopy = &H80040306
        DiskError = &H80040116
        DiskFull = 4
        EndOfSession = &H80040200
        ErrorsReturned = &H40380
        ExtendedError = &H80040119
        Fail = &H80004005
        FailOneProvider = &H8004011D
        Failure = 2
        FolderCycle = &H8004060B
        HasFolders = &H80040609
        HasMessages = &H8004060A
        InsufficientMemory = 5
        InterfaceNotSupported = &H80004002
        InvalidAccessTime = &H80040123
        InvalidArg = &H80070057
        InvalidBookmark = &H80040405
        InvalidEditFields = &H18
        InvalidEntryId = &H80040107
        InvalidMessage = &H11
        InvalidObject = &H80040108
        InvalidParameter = &H80070057
        InvalidRecips = &H19
        InvalidSession = &H13
        InvalidType = &H80040302
        InvalidWorkstationAccount = &H80040122
        LogonFailed = &H80040111
        LogonFailure = 3
        MessageInUse = &H16
        MissingRequiredColumn = &H80040202
        NetworkError = &H80040115
        NetworkFailure = &H17
        NoAccess = &H80070005
        NoInterface = &H80004002
        NoMessages = &H10
        NonStandard = &H80040606
        NoRecipients = &H80040607
        NoService = &H40203
        NoSupport = &H80040102
        NoSuppress = &H80040602
        NotEnoughDisk = &H8004010D
        NotEnoughMemory = &H8007000E
        NotEnoughResources = &H8004010E
        NotFound = &H8004010F
        NotInitialized = &H80040605
        NotInQueue = &H80040601
        NotMe = &H80040502
        NotSupported = &H1A
        ObjectChanged = &H80040109
        ObjectDeleted = &H8004010A
        OutOfMemory = &H8007000E
        PartialCompletion = &H40680
        PasswordChangeRequired = &H80040120
        PasswordExpired = &H80040121
        PositionChanged = &H40481
        SessionLimit = &H80040112
        StringTooLong = &H80040105
        Submitted = &H80040608
        Success = 0
        TableEmpty = &H80040402
        TableTooBig = &H80040403
        TextTooLarge = &H12
        Timeout = &H80040401
        TooBig = &H80040305
        TooComplex = &H80040117
        TooManyFiles = 9
        TooManyRecipients = 10
        TooManySessions = 8
        TypeNoSupport = &H80040303
        TypeNotSupported = 20
        UnableToAbort = &H80040114
        UnableToComplete = &H80040400
        Unconfigured = &H8004011C
        UnexpectedId = &H80040307
        UnexpectedType = &H80040304
        UnknownCpid = &H8004011E
        UnknownEntryid = &H80040201
        UnknownFlags = &H80040106
        UnknownLcid = &H8004011F
        UnknownRecipient = 14
        USER_ABORT = 1
        UserCancel = &H80040113
        Version = &H80040110
        Wait = &H80040500

    End Enum

    <Flags()> _
    Enum MapiFlags
        [Default] = 0
        DefaultServices = 1
        Dialog = 8
        Unicode = -2147483648
    End Enum

#Region "Public enumerations for MailMessage class"

    ''' <summary>
    ''' Describes the delivery notification options for e-mail.
    ''' </summary>
    <Flags()> _
    Public Enum DeliveryNotificationOptions
        ''' <summary>
        ''' Notify if the delivery is delayed  
        ''' </summary>
        Delay = 4
        ''' <summary>
        '''  Never notify.  
        ''' </summary>
        Never = 134217728
        ''' <summary>
        ''' No notification.  
        ''' </summary>
        None = 0
        ''' <summary>
        '''  Notify if the delivery is unsuccessful.  
        ''' </summary>
        OnFailure = 2
        ''' <summary>
        '''  Notify if the delivery is successful.  
        ''' </summary>
        OnSuccess = 1
    End Enum

    ''' <summary>
    ''' Enumeration for Encoding opitons.
    ''' </summary>
    <Flags()> _
    Public Enum EncodingOptions

        ''' <summary>
        ''' Gets an encoding for the ASCII (7-bit) character set.
        ''' </summary>
        ASCII
        ''' <summary>
        ''' Gets an encoding for the UTF-16 format using the big endian byte order.
        ''' </summary>
        BigEndianUnicode
        ''' <summary>
        ''' Gets an encoding for the system's current ANSI code page.
        ''' </summary>
        [Default]
        ''' <summary>
        ''' Gets an encoding for the UTF-16 format using the little endian byte order.
        ''' </summary>
        Unicode
        ''' <summary>
        ''' Gets an encoding for the UTF-32 format using the little endian byte order.
        ''' </summary>
        UTF32
        ''' <summary>
        ''' Gets an encoding for the UTF-7 format.
        ''' </summary>
        UTF7
        ''' <summary>
        ''' Gets an encoding for the UTF-8 format.
        ''' </summary>
        UTF8
    End Enum

    ''' <summary>
    ''' Priority options for sending mail.
    ''' </summary>
    <Flags()> _
   Public Enum Priorities

        ''' <summary>
        '''  The email has normal priority. 
        ''' </summary>
        Normal
        ''' <summary>
        ''' The email has low priority.  
        ''' </summary>
        Low
        ''' <summary>
        ''' The email has high priority.  
        ''' </summary>
        High
    End Enum

    ''' <summary>
    ''' Enumerations for message body views.
    ''' </summary>
    <Flags()> _
    Public Enum AlternateBodyViews

        ''' <summary>
        ''' Specifies data is in plain text format.
        ''' </summary>
        Plain
        ''' <summary>
        ''' Specifies data is in HTML format.
        ''' </summary>
        Html
        ''' <summary>
        ''' Specifies data is in rich text format(RTF).
        ''' </summary>
        RichText
        ''' <summary>
        ''' Specifies data is in XML format.
        ''' </summary>
        Xml
    End Enum

#End Region

#End Region
End Namespace


